package utils;

import lombok.Data;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author 19242
 */
@Data
public class Name {

    private String sql;

    private Integer from;

    private Integer size;

    public Name(String sql) {
        this.sql = sql;
    }

    public String desc() {

        List<String> items = new ArrayList<>(Arrays.asList(sql.split(" ")));
        return foreach(items).replace("(.", "(new BoolQueryBuilder().");
    }

    private String foreach(List<String> items) {
        ArrayStack<String> query = new ArrayStack<>(items.size());
        ArrayStack<Integer> bool = new ArrayStack<>(items.size());
        for (int i = 0; i < items.size();) {
            String field = items.get(i++);
            if (i >= items.size()){
                break;
            }
            String condition = items.get(i++);
            if (i >= items.size()){
                break;
            }
            String value = items.get(i++);
            String c = String.format("QueryBuilders.termQuery(\"%s\", \"%s\")", field, value);
            query.push(c);
            if (i >= items.size()){
                break;
            }
            String relation = items.get(i++);

            bool.push("and".equalsIgnoreCase(relation) ? 1 : 0);
            if (i >= items.size()){
                break;
            }
            extracted(query, bool);

        }
        while (query.stack.size() > 1){
            String queryPop = query.pop();
            String queryPop1 = query.pop();
            Integer boolPop = bool.pop();
            query.push(String.format(boolPop == 1 ? ".must(%s)\n.must(%s)" : ".should(%s)\n.should(%s)", queryPop1, queryPop));
        }

        return query.pop();
    }

    private void extracted(ArrayStack<String> query, ArrayStack<Integer> bool) {
        if (query.stack.size() >= 2 && bool.stack.size() >= 2){
            String queryPop = query.pop();
            String queryPop1 = query.pop();
            Integer boolPop = bool.pop();
            Integer boolPop1 = bool.pop();
            int max = boolPop1;
            if (boolPop1 >= boolPop){
                bool.push(boolPop);
            }else {
                query.push(queryPop1);
                query.push(queryPop);
                bool.push(boolPop1);
                bool.push(boolPop);
                return;
            }
            query.push(String.format(max == 1 ? ".must(%s)\n.must(%s)" : ".should(%s)\n.should(%s)", queryPop1, queryPop));
        }
    }
}
